#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1e5 + 5;

struct node{
    int l, r;
    friend bool operator < (node x, node y) {
        if (x.l == y.l)
            return x.r < y.r;
        return x.l < y.l;
    }
}a[N];

int n, m, L, V;
int c[N];
int cnt[N * 10];
int lst[N * 10];
bool p[N];

signed main() {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    int T;
    cin >> T;
    while (T--) {
        memset(cnt, 0, sizeof(cnt));
        memset(lst, -1, sizeof(lst));
        memset(p, 0, sizeof(p));
        scanf("%lld%lld%lld%lld", &n, &m, &L, &V);
        for (int i = 1; i <= n; i++) {
            int d, v, A;
            scanf("%lld%lld%lld", &d, &v, &A);
            if (v > V) {
                if (A >= 0)
                    a[i].l = d, a[i].r = L;
                else {
                    a[i].l = d;
                    a[i].r = min((int)ceil(((double)V * (double)V - (double)v * (double)v) / (2.0 * (double)A)) + d - 1 , L);
                }
            }
            else {
                if (A <= 0)
                    a[i].l = a[i].r = L + 2;
                else {
                    a[i].l = min((int)floor(((double)V * (double)V - (double)v * (double)v) / (2.0 * (double)A)) + d + 1, L + 2);
                    a[i].r = max(a[i].l, L);
                }
            }
            //cout << a[i].l << ' ' << a[i].r << '\n';
        }
        for (int i = 1; i <= m; i++)
            scanf("%lld", &c[i]);
        for (int i = 1; i <= m; i++)
            cnt[c[i]]++;
        lst[0] = cnt[0] - 1;
        for (int i = 1; i <= L; i++)
            lst[i] = (cnt[i] ? i : lst[i - 1]);
        int tmp = 0;
        for (int i = 1; i <= n; i++) {
            if (!a[i].l)
                tmp++, p[i] = 1;
            else if (lst[a[i].l - 1] != lst[a[i].r])
                tmp++, p[i] = 1;
        }
        printf("%lld ", tmp);
        if (n <= 20 && m <= 20) {
            int ans = 0;
            for (int i = 0; i < (1 << m); i++) {
                int cnt = 0;
                map<int, int> mp;
                for (int j = 1; j <= m; j++) {
                    if ((1 << (j - 1)) & i)
                        for (int k = 1; k <= n; k++)
                            if ((a[k].l <= c[j] && a[k].r >= c[j]) || (!p[k])) {
                                mp[k] = 1;
                            }
                }
                bool f = 1;
                for (int j = 1; j <= n; j++)
                    if (!mp[j]) {
                        f = 0;
                    }
                if (f) {
                    //cout << i << '\n';
                    ans = max(ans, m - __builtin_popcount(i));
                }
            }
            printf("%lld\n", ans);
        }
        else {
            if (!tmp)
                cout << m << '\n';
            else
                cout << m - 1 << '\n';
        }
    }
    return 0;
}
/*
1
10 10 175391 226
31181 234 -546
32757 670 -9
43723 775 -3
78541 862 -4
26626 961 -13
54690 759 -998
56165 659 -3
56531 776 -34
32860 950 -6
86709 145 47
31182 33025 46753 52673 57685 60635 99569 124240 162898 170704
*/

/*
dp, segment tree, hash, kmp, maths, greedy, graph
*/
